from robyn import SubRouter
from robyn.robyn import Request, Response

from constants import HttpStatus
from middleware.auth_middleware import auth_required
from models.dao import permission_dao
from utils.error_handler import unified_response
from services import permission_service, user_service
from utils.jwt_util import verify_access_token

menu_controller = SubRouter(__file__, prefix="/api")

def _format_menu_for_frontend(menu_item):
    formatted_menu = {
        "name": menu_item.get("name"),
        "path": menu_item.get("endpoint"),
        "component": menu_item.get("component"),
        "redirect": menu_item.get("redirect"),
        "meta": {
            "order": menu_item.get("order"),
            "title": menu_item.get("name"), # Using name as title for now
            "icon": menu_item.get("icon"),
            "badgeType": menu_item.get("badgeType"),
            "badgeVariants": menu_item.get("badgeVariants"),
            "noBasicLayout": menu_item.get("noBasicLayout", False), # <--- 添加这一行
        }
    }
    if menu_item.get("children"):
        formatted_menu["children"] = [_format_menu_for_frontend(child) for child in menu_item["children"]]
    return formatted_menu

@menu_controller.get("/menu/all")
@auth_required()
async def get_menus_all(request: Request) -> Response:
    """
    获取菜单列表
    从权限表生成菜单
    """
    tokenstr = request.headers['authorization']
    token_type, token = tokenstr.split(" ", 1)
    payload = verify_access_token(token)
    user = payload.get("user_id")

    try:
        menus_from_db = permission_service.getPermissionsByUser(ismenu=True, user_id=user)
        
        menus_from_db.sort(key=lambda x: (x.get("order") is None, x.get("order", 0)))
        formatted_menus = [_format_menu_for_frontend(menu) for menu in menus_from_db]

        return unified_response(HttpStatus.OK, "菜单获取成功", formatted_menus)

    except Exception as e:
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "获取菜单失败", None, error=str(e))

def _format_system_menu(menu_item):
    """格式化为SystemMenu接口格式"""
    # 优先使用title，当title为空时使用name
    title = menu_item.get("title") or menu_item.get("name") or ""
    
    formatted_menu = {
        "id": menu_item.get("id"),
        "name": menu_item.get("name"),
        "path": menu_item.get("endpoint"),
        "component": menu_item.get("component"),
        "redirect": menu_item.get("redirect"),
        "pid": menu_item.get("parent_id", ""),
        "authCode": menu_item.get("name"),  # 使用name作为权限标识
        "type": menu_item.get("permissionType", "menu"),  # 默认类型为menu
        "meta": {
            "title": title,  # 使用处理后的title
            "icon": menu_item.get("icon"),
            "order": menu_item.get("order"),
            "badgeType": menu_item.get("badgeType"),
            "badgeVariants": menu_item.get("badgeVariants"),
            "noBasicLayout": menu_item.get("noBasicLayout", False),
            "hideInMenu": menu_item.get("hideInMenu", False),
            "hideInTab": menu_item.get("hideInTab", False),
            "hideInBreadcrumb": menu_item.get("hideInBreadcrumb", False),
            "hideChildrenInMenu": menu_item.get("hideChildrenInMenu", False),
            "keepAlive": menu_item.get("keepAlive", True),
            "affixTab": menu_item.get("affixTab", False),
            "openInNewWindow": menu_item.get("openInNewWindow", False),
        }
    }
    
    # 处理children，构建树形结构
    if menu_item.get("children"):
        formatted_menu["children"] = [_format_system_menu(child) for child in menu_item["children"]]
    
    return formatted_menu

# 修改get_menus_list函数
@menu_controller.get("/menu/list")
@auth_required()
async def get_menus_list(request: Request) -> Response:
    """
    获取菜单列表 - 返回SystemMenu格式
    """
    try:
        # 获取权限数据并构建树形结构
        menus_from_db = permission_service.getPermissions()
        
        # 按order排序
        menus_from_db.sort(key=lambda x: (x.get("order") is None, x.get("order", 0)))
        
        # 格式化为SystemMenu接口格式
        formatted_menus = [_format_system_menu(menu) for menu in menus_from_db]

        return unified_response(HttpStatus.OK, "菜单获取成功", formatted_menus)

    except Exception as e:
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "获取菜单失败", None, error=str(e))

@menu_controller.get("/system/menu/name-exists")
@auth_required()
async def is_menu_name_exists(request: Request) -> Response:
    """
    检查菜单名称是否存在
    处理name参数为空的情况
    """
    try:
        menu_id = request.query_params.get("id", "")
        name = request.query_params.get("name", "")


        # 如果name为空，返回不存在(false)
        if not name or name.strip() == "":
            return unified_response(HttpStatus.OK, "查询成功", False)

        # 检查名称是否存在（排除当前菜单ID）
        exists = permission_service.menu_name_exists(name, menu_id)
        return unified_response(HttpStatus.OK, "查询成功", exists)

    except Exception as e:
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "查询失败", None, error=str(e))

@menu_controller.get("/system/menu/path-exists")
@auth_required()
async def is_menu_path_exists(request: Request) -> Response:
    """
    检查菜单路径是否存在
    """
    try:
        menu_id = request.query_params.get("id", "")
        path = request.query_params.get("path", "")


        if not path:
            # return unified_response(HttpStatus.BAD_REQUEST, "菜单路径不能为空")
            return unified_response(HttpStatus.OK, "查询成功", False)
        exists = permission_service.menu_path_exists(path, menu_id)
        return unified_response(HttpStatus.OK, "查询成功", exists)

    except Exception as e:
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "查询失败", None, error=str(e))

@menu_controller.post("/system/menu")
@auth_required()
async def create_menu(request: Request) -> Response:
    """
    创建菜单
    接收前端发送的SystemMenu格式数据
    """
    try:
        # 获取请求数据
        data = request.json()
        if not data:
            return unified_response(HttpStatus.BAD_REQUEST, "请求数据不能为空", None)

        # 提取必要字段
        menu_id = data.get("id")
        auth_code = data.get("authCode")
        component = data.get("component", "")
        path = data.get("path", "")
        redirect = data.get("redirect", "")
        parent_id = data.get("pid", "")
        permissionType = data.get("type", "menu")
        # 处理meta字段
        meta = data.get("meta", {})
        # 确保meta是字典类型，如果不是则转换或重置
        if isinstance(meta, str):
            try:
                import json
                meta = json.loads(meta) if meta.strip() else {}
            except (json.JSONDecodeError, ValueError):
                meta = {}
        elif not isinstance(meta, dict):
            meta = {}

        title = meta.get("title", "")
        icon = meta.get("icon", "")
        order = meta.get("order", 0)
        badge_type = meta.get("badgeType", "")
        badge_variants = meta.get("badgeVariants", "")
        no_basic_layout = meta.get("noBasicLayout", False)
        hide_in_menu = meta.get("hideInMenu", False)
        hide_in_tab = meta.get("hideInTab", False)
        hide_in_breadcrumb = meta.get("hideInBreadcrumb", False)
        hide_children_in_menu = meta.get("hideChildrenInMenu", False)
        keep_alive = meta.get("keepAlive", True)
        affix_tab = meta.get("affixTab", False)
        open_in_new_window = meta.get("openInNewWindow", False)

        # 构建菜单数据
        menu_data = {
            "id": menu_id,
            "name": title,  # 使用authCode作为权限标识
            "endpoint": path,
            "component": component,
            "redirect": redirect,
            "parent_id": parent_id,
            "permissionType": permissionType,
            "order": order,
            "icon": icon,
            "title": title,
            "badgeType": badge_type,
            "badgeVariants": badge_variants,
            "noBasicLayout": no_basic_layout,
            "hideInMenu": hide_in_menu,
            "hideInTab": hide_in_tab,
            "hideInBreadcrumb": hide_in_breadcrumb,
            "hideChildrenInMenu": hide_children_in_menu,
            "keepAlive": keep_alive,
            "affixTab": affix_tab,
            "openInNewWindow": open_in_new_window
        }

        # 处理子菜单
        children = data.get("children", [])
        if children:
            menu_data["children"] = children

        # 保存菜单数据
        result = permission_service.save_menu(menu_data)

        if result:
            return unified_response(HttpStatus.OK, "菜单保存成功", result)
        else:
            return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "菜单保存失败", None)

    except Exception as e:
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "菜单保存失败", None, error=str(e))


@menu_controller.put("/system/menu/:id")
@auth_required()
async def update_menu(request: Request) -> Response:
    """
    更新菜单
    接收前端发送的SystemMenu格式数据
    """
    try:
        id = request.path_params.get("id")
        # 获取请求数据
        data = request.json()
        if not data:
            return unified_response(HttpStatus.BAD_REQUEST, "请求数据不能为空", None)

        # 提取必要字段
        # menu_id = data.get("id")
        menu_id = id
        name = data.get("name", "")
        auth_code = data.get("authCode")
        component = data.get("component", "")
        path = data.get("path", "")
        redirect = data.get("redirect", "")
        parent_id = data.get("pid", "")
        permissionType = data.get("type", "menu")
        # 处理meta字段
        meta = data.get("meta", {})
        # 确保meta是字典类型，如果不是则转换或重置
        if isinstance(meta, str):
            try:
                import json
                meta = json.loads(meta) if meta.strip() else {}
            except (json.JSONDecodeError, ValueError):
                meta = {}
        elif not isinstance(meta, dict):
            meta = {}

        title = meta.get("title", "")
        icon = meta.get("icon", "")
        order = meta.get("order", 0)
        badge_type = meta.get("badgeType", "")
        badge_variants = meta.get("badgeVariants", "")
        no_basic_layout = meta.get("noBasicLayout", False)
        hide_in_menu = meta.get("hideInMenu", False)
        hide_in_tab = meta.get("hideInTab", False)
        hide_in_breadcrumb = meta.get("hideInBreadcrumb", False)
        hide_children_in_menu = meta.get("hideChildrenInMenu", False)
        keep_alive = meta.get("keepAlive", True)
        affix_tab = meta.get("affixTab", False)
        open_in_new_window = meta.get("openInNewWindow", False)

        # 构建菜单数据
        menu_data = {
            "id": menu_id,
            "name": title,  # 使用authCode作为权限标识
            "endpoint": path,
            "component": component,
            "redirect": redirect,
            "parent_id": parent_id,
            "permissionType": permissionType,
            "order": order,
            "icon": icon,
            "title": title,
            "badgeType": badge_type,
            "badgeVariants": badge_variants,
            "noBasicLayout": no_basic_layout,
            "hideInMenu": hide_in_menu,
            "hideInTab": hide_in_tab,
            "hideInBreadcrumb": hide_in_breadcrumb,
            "hideChildrenInMenu": hide_children_in_menu,
            "keepAlive": keep_alive,
            "affixTab": affix_tab,
            "openInNewWindow": open_in_new_window
        }

        # 处理子菜单
        children = data.get("children", [])
        if children:
            menu_data["children"] = children

        # 保存菜单数据
        result = permission_service.save_menu(menu_data)

        if result:
            return unified_response(HttpStatus.OK, "菜单保存成功", result)
        else:
            return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "菜单保存失败", None)

    except Exception as e:
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "菜单保存失败", None, error=str(e))


@menu_controller.delete("/system/menu/:id")
@auth_required()
async def delete_menu(request: Request) -> Response:
    """
    删除菜单
    接收前端发送的菜单ID，支持批量删除子菜单
    """
    try:
        # 从路径参数中获取菜单ID
        menu_id = request.path_params.get("id")

        # 验证menu_id是否存在
        if not menu_id:
            return unified_response(HttpStatus.BAD_REQUEST, "菜单ID不能为空", None)

        # 检查菜单是否存在
        menu = permission_service.getPermission(menu_id)
        if not menu:
            return unified_response(HttpStatus.NOT_FOUND, "菜单不存在", None)

        # 调用服务层删除菜单（包含子菜单）
        is_deleted = permission_service.delete_menu(menu_id)

        if is_deleted:
            return unified_response(HttpStatus.OK, "菜单删除成功", None)
        else:
            return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "菜单删除失败", None)

    except Exception as e:
        # 捕获异常并返回错误响应
        return unified_response(HttpStatus.INTERNAL_SERVER_ERROR, "删除菜单时发生错误", None, error=str(e))